﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.Diagnostics;

namespace _1945
{
    class Player : GameObject
    {

        #region Variables
        int lives;
        int health = 70;
        int maxHealth = 100;
        public int Lives { get { return lives; } }
        public int Score { get { return score; } }
        int bulletDamage = 20;
        public int BulletDamage { get { return bulletDamage; } }

        Vector2 startPosition;
        Vector2 playerCannonPosition = Vector2.Zero;
        
        List<GameObject> bullets;
        Sprite bullet;
        
        KeyboardState keyboard;
        
        TimeSpan fireDelay = new TimeSpan();
        TimeSpan lastFire = new TimeSpan();

        TimeSpan timeInvincible = new TimeSpan(0, 0, 3);
        TimeSpan timeOfDeath;

        bool isInvincible = false;
        public bool IsInvincible { get { return isInvincible; } }

        private Color tint = Color.White;
        #endregion

        #region Constructors

        public Player(Game game, Texture2D _gameSprite, Vector2 _startpos, Vector2 _speed, int _lives, int bulletsPerSecond, Vector2 _direction, Sprite sprite, Rectangle _gameScreenBounds, Sprite bullet ,List<GameObject> _bullets)
            : base(game, _gameSprite, _startpos, _speed, _direction, sprite, _gameScreenBounds)
        {
            lives = _lives;
            startPosition = _startpos;

            fireDelay = new TimeSpan(10000000 / bulletsPerSecond);

            bullets = _bullets;
            this.bullet = bullet;

            /*
            isInvincible = true;
            timeOfDeath = new TimeSpan(3000000,30000000, 0, 0);
            tint.A = 100;
            */ 
        }

        #endregion

        private void moveShip(KeyboardState keyboard)
        {
            if (keyboard.IsKeyDown(Keys.Up))
            {
                position.Y -= speed.Y;
            }
            if (keyboard.IsKeyDown(Keys.Down))
            {
                position.Y += speed.Y;
            }
            if (keyboard.IsKeyDown(Keys.Left))
            {
                position.X -= speed.X;
            }
            if (keyboard.IsKeyDown(Keys.Right))
            {
                position.X += speed.X;
            }
            
            // Keep the ship inside the screen
            if (position.X < gameScreenBounds.Left)
            {
                position.X = gameScreenBounds.Left;
            }

            if (position.X > gameScreenBounds.Width - sprite.getWidth())
            {
                position.X = gameScreenBounds.Width - sprite.getWidth();
            }
            if (position.Y < gameScreenBounds.Top)
            {
                position.Y = gameScreenBounds.Top;
            }
            if (position.Y > gameScreenBounds.Height - sprite.getHeight())
            {
                position.Y = gameScreenBounds.Height - sprite.getHeight();
            }
        }

        private void fireBullet(GameTime gameTime)
        {
            keyboard = Keyboard.GetState();

            if (gameTime.TotalGameTime.Subtract(lastFire).CompareTo(fireDelay) > 0)
            {
                if (keyboard.IsKeyDown(Keys.Space)){
                    bullets.Add(new GameObject(Game, gameSpriteSheet, playerCannonPosition, new Vector2(5), new Vector2(0, -1), bullet, gameScreenBounds));
                    lastFire = gameTime.TotalGameTime;
                }
            }
        
        }

        //Where playerBullets should fire from
        private void setPlayerCannonPosition(){
            playerCannonPosition.X = position.X + sprite.getWidth() / 2 - bullet.getWidth() / 2;
            playerCannonPosition.Y = position.Y;
        }

        /// <summary>
        /// Updates player score
        /// </summary>
        /// <param name="How many points to increase player score with"></param>
        public void updateScore(int x)
        {
            score += x;
        }

        public void damage(int hitPoints, GameTime gameTime)
        {
            health -= hitPoints;

            if (health <= 0)
            {
                this.explode(gameTime);
                health = maxHealth;
                bulletDamage = 20;
            }
        }

        public void addHealth(int addHealth)
        {
            if (this.health < maxHealth)
            {
                this.health += addHealth;
                if (this.health > maxHealth)
                {
                    this.health = maxHealth;
                }
            }
        }

        public void addBulletPower(int addBulletPower)
        {
            bulletDamage +=addBulletPower;
        }

        public override void Update(GameTime gameTime)
        {
            setPlayerCannonPosition();
            keyboard = Keyboard.GetState();

            //Become invincible
            if (keyboard.IsKeyDown(Keys.I))
            {
                isInvincible = true;
                timeOfDeath = gameTime.TotalGameTime.Add(new TimeSpan(1,0,0));
                tint.A = 100;
            }

            //Die
            if (keyboard.IsKeyDown(Keys.D))
            {
                explode(gameTime);
            }

            if (!isExploding)
            {
                moveShip(keyboard);
                fireBullet(gameTime);
            }
            
            if (gameTime.TotalGameTime.Subtract(timeOfDeath).CompareTo(timeInvincible) > 0 && isInvincible)
            {
                isInvincible = false;
                tint = Color.White;
            }
            
            if (hasExploded)
            {
                isExploding = false;
                hasExploded = false;
                lives--;
                position = startPosition;
                timeOfDeath = gameTime.TotalGameTime;
                isInvincible = true;
                sprite = spriteFactory.getPlayerSprite(SpriteFactory.player.bigShipWithShadow);
                tint.A = 100;
            }
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            spriteBatch.Draw(gameSpriteSheet, position, sprite.getSpriteRectangle(), tint);
            //health bar
            spriteBatch.Draw(blackTexture, new Vector2(70, 30), new Rectangle(100, 101, 100, 20), new Color(255, 255, 255, 50));
            spriteBatch.Draw(blackTexture, new Vector2(70, 30), new Rectangle(100, 101, 100 * health/maxHealth, 20), Color.GreenYellow);
            spriteBatch.DrawString(spriteFont, "Lives: " + lives, new Vector2(0, 0), Color.White);
            spriteBatch.DrawString(spriteFont, "Score: " + score, new Vector2(80, 0), Color.White);
            spriteBatch.DrawString(spriteFont, "Health", new Vector2(0, 30), Color.White);
            spriteBatch.DrawString(spriteFont, "Power: " + bulletDamage.ToString(), new Vector2(0, 60), Color.White);
            //base.Draw(gameTime);
        }
    }
}
